using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using MageDefender.GameClasses;
using MageDefender.Interfaces;


namespace MageDefender
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class TheGame : Microsoft.Xna.Framework.DrawableGameComponent
    {
        enum SceneManager { Intro = 1, PressStart = 2, MainMenu, InGame, Shop, Tutorial, Story, GameOver, Credits };

        Scenes.IntroScene introScene;
        Scenes.LevelScene levelScene;
        Scenes.ShopScene shopScene;
        Scenes.TutorialScene tutorialScene;
        Scenes.MainMenuScene mainMenuScene;
        Scenes.StoryScene storyScene;
        Scenes.GameOverScene gameOverScene;
        Scenes.PressStartScene pressStartScene;
        Scenes.CreditsScene creditsScene;

        AudioEngine engine;
        SoundBank soundBank;
        WaveBank waveBank;
        Cue menuCue;
        Cue ingameCue;

        SceneManager sceneManager;

        public TheGame(Game game)
            : base(game)
        {
            sceneManager = new SceneManager();
            sceneManager = SceneManager.Intro;

            levelScene = new global::MageDefender.Scenes.LevelScene(game);
            introScene = new global::MageDefender.Scenes.IntroScene(game);
            shopScene = new global::MageDefender.Scenes.ShopScene(game);
            tutorialScene = new global::MageDefender.Scenes.TutorialScene(game);
            mainMenuScene = new global::MageDefender.Scenes.MainMenuScene(game);
            storyScene = new global::MageDefender.Scenes.StoryScene(game);
            gameOverScene = new global::MageDefender.Scenes.GameOverScene(game);
            pressStartScene = new global::MageDefender.Scenes.PressStartScene(game);
            creditsScene = new global::MageDefender.Scenes.CreditsScene(game);


            engine = new AudioEngine("Content\\music.xgs");
            soundBank = new SoundBank(engine, "Content\\SoundBank.xsb");
            waveBank = new WaveBank(engine, "Content\\WaveBank.xwb");

            menuCue = soundBank.GetCue("menuMusic");
            ingameCue = soundBank.GetCue("ingameMusic");
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            levelScene.Initialize();
            introScene.Initialize();
            shopScene.Initialize();
            tutorialScene.Initialize();
            mainMenuScene.Initialize();
            storyScene.Initialize();
            gameOverScene.Initialize();
            pressStartScene.Initialize();
            creditsScene.Initialize();
            // TODO: Add your initialization code here

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            engine.Update();

            switch(sceneManager)
            {
                case SceneManager.Credits:
                    {
                        creditsScene.Update(gameTime);
                        if (creditsScene.StartGame)
                        {
                            creditsScene.StartGame = false;
                            sceneManager = SceneManager.MainMenu;
                        }
                        break;
                    }
                case SceneManager.InGame:
                    {
                        levelScene.Update(gameTime);
                        if (levelScene.IsWaveFinished)
                        {
                            if (levelScene.TheWaveWasABoss())
                            {
                                sceneManager = SceneManager.Story;
                            }
                            else sceneManager = SceneManager.Shop;

                            levelScene.StartNewWave();
                            IFort castle = (IFort)Game.Services.GetService(typeof(IFort));
                            
                            menuCue.Stop(AudioStopOptions.Immediate);
                            ingameCue.Stop(AudioStopOptions.Immediate);

                            menuCue = soundBank.GetCue("menuMusic");
                            if (!menuCue.IsPlaying)
                            {
                                menuCue.Play();
                            }


                        }
                        if (levelScene.IsGameOver())
                        {
                            sceneManager = SceneManager.GameOver;
                        }
                        break;
                    }
                case SceneManager.Shop:
                    {
                        shopScene.Update(gameTime);
                        if (shopScene.StartNextWave)
                        {
                            menuCue.Stop(AudioStopOptions.Immediate);
                            ingameCue.Stop(AudioStopOptions.Immediate);

                            ingameCue = soundBank.GetCue("ingameMusic");
                            if (!ingameCue.IsPlaying)
                            {
                                ingameCue.Play();
                            }

                            shopScene.StartNextWave = false;
                            sceneManager = SceneManager.InGame;
                        }
                        break;
                    }
                case SceneManager.Intro:
                    {
                        introScene.Update(gameTime);
                        if (introScene.ChangeScene)
                        {
                            menuCue.Stop(AudioStopOptions.Immediate);
                            ingameCue.Stop(AudioStopOptions.Immediate);

                            menuCue = soundBank.GetCue("menuMusic");
                            if (!menuCue.IsPlaying)
                            {
                                menuCue.Play();
                            }

                            introScene.ChangeSceneTimer = 0;
                            introScene.ChangeScene = false;
                            sceneManager = SceneManager.PressStart;
                        }
                        break;
                    }
                case SceneManager.Tutorial:
                    {
                        tutorialScene.Update(gameTime);
                        if (tutorialScene.StartGame)
                        {
                            tutorialScene.StartGame = false;
                            sceneManager = SceneManager.InGame;
                            menuCue.Stop(AudioStopOptions.Immediate);
                            ingameCue.Stop(AudioStopOptions.Immediate);

                            ingameCue = soundBank.GetCue("ingameMusic");
                            if (!ingameCue.IsPlaying)
                            {
                                ingameCue.Play();
                            }
                        }
                        break;
                    }
                case SceneManager.MainMenu:
                    {
                        mainMenuScene.Update(gameTime);
                        if (mainMenuScene.StartGame)
                        {
                            mainMenuScene.StartGame = false;
                            sceneManager = SceneManager.Story;
                            storyScene.DisplayStoryNumber = 1;
                            mainMenuScene.SelectTimer = 200;
                        }
                        if (mainMenuScene.ShowCredits)
                        {
                            mainMenuScene.ShowCredits = false;
                            mainMenuScene.SelectTimer = 200;
                            sceneManager = SceneManager.Credits;
                        }

                        break;
                    }
                case SceneManager.Story:
                    {
                        if (levelScene.Castle.TheCastle.Wave >= 2 && levelScene.Castle.TheCastle.Wave < 10)
                        {
                            storyScene.DisplayStoryNumber = 2;
                        }
                        if (levelScene.Castle.TheCastle.Wave >= 20 && levelScene.Castle.TheCastle.Wave < 100)
                        {
                            storyScene.DisplayStoryNumber = 3;
                        }

                        storyScene.Update(gameTime);
                        if (storyScene.StartGame)
                        {
                            storyScene.StartGame = false;
                            sceneManager = SceneManager.Tutorial;
                            if (levelScene.Castle.TheCastle.Wave > 1)
                            {
                                sceneManager = SceneManager.Shop;
                            }
                        }
                        break;
                    }
                case SceneManager.GameOver:
                    {
                        gameOverScene.Update(gameTime);
                        if (gameOverScene.StartGame)
                        {
                            gameOverScene.StartGame = false;
                            sceneManager = SceneManager.MainMenu;
                        }
                        break;
                    }
                case SceneManager.PressStart:
                    {
                        pressStartScene.Update(gameTime);
                        if (pressStartScene.StartGame)
                        {
                            pressStartScene.StartGame = false;
                            sceneManager = SceneManager.MainMenu;
                        }
                        break;
                    }

            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            switch (sceneManager)
            {
                case SceneManager.Credits:
                    {
                        creditsScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.InGame:
                    {
                        levelScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.Shop:
                    {
                        shopScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.Intro:
                    {
                        introScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.Tutorial:
                    {
                        tutorialScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.MainMenu:
                    {
                        mainMenuScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.Story:
                    {
                        storyScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.GameOver:
                    {
                        gameOverScene.Draw(gameTime);
                        break;
                    }
                case SceneManager.PressStart:
                    {
                        pressStartScene.Draw(gameTime);
                        break;
                    }
            }
            base.Draw(gameTime);
        }
    }
}